package com.icw.decoupling.impl.tool;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

import com.icw.basis.MyRunnable;
import com.icw.decoupling.defi.tool.ThreadPoolManager;
import com.icw.utility.IcwUtils;

@Component
public class DefaultThreadPoolManager implements ThreadPoolManager, DisposableBean {

	public final ThreadPoolExecutor POOL;

	public DefaultThreadPoolManager() {
		POOL = new ThreadPoolExecutor(1, 100, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>(5));
	}

	@Override
	public void submit(MyRunnable... run_err_suc_fnl) {
		this.submitx(run_err_suc_fnl[0]// e
				, run_err_suc_fnl.length > 1 ? run_err_suc_fnl[1] : EMPTY_RUN// e
				, run_err_suc_fnl.length > 2 ? run_err_suc_fnl[2] : EMPTY_RUN// e
				, run_err_suc_fnl.length > 3 ? run_err_suc_fnl[3] : EMPTY_RUN// e
		);
	};

	@Override
	public <T> T submitTask(Callable<T> run_err_suc_fnl) throws Exception {
		FutureTask<T> f = new FutureTask<T>(run_err_suc_fnl);
		new Thread(f).start();
		return f.get(5, TimeUnit.SECONDS);
	};

	void submitx(MyRunnable run, MyRunnable success, MyRunnable error, MyRunnable complete) {
		POOL.submit(() -> {
			try {
				run.run();
				success.run();
			} catch (Exception e) {
				IcwUtils.tryCatch(error);
			} finally {
				IcwUtils.tryCatch(complete);
			}
		});
	}

	private static final MyRunnable EMPTY_RUN = () -> {
	};

	@Override
	public void destroy() throws Exception {
		POOL.shutdown();
	}
}
